package ss.pku.jsa.type.preference;

import java.io.File;
import java.io.IOException;

import org.eclipse.jface.preference.BooleanFieldEditor;
import org.eclipse.jface.preference.FieldEditorPreferencePage;
import org.eclipse.jface.preference.FileFieldEditor;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.preference.PreferenceStore;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;

import ss.pku.jsa.type.inference.JqualPlugin;

public class JqualPreferencePage extends FieldEditorPreferencePage implements
		IWorkbenchPreferencePage {
	public static final String P_LATTICE = "latticePreference";
	public static final String P_DEBUG = "debugPreference";
	public static final String P_PROFILE = "profilePreference";
	public static final String CONTEXT_SENS = "contextSensitive";
	public static final String P_TYPECLOSURE = "typeClosurePreference";
	public static final String P_LONGNAMES = "useLongQualifierNamesPreference";
	public static final String P_EMPTYQUALS = "showEmptyQualifiersPreference";
	public static final String P_ALLOWMERGE = "allowMerge";
	public static final String P_FIELDSENS = "fieldSensitive";
	public static final String P_FIELD_SENS_ANNOTS = "obeyfieldSensitiveMarkups";
	public static final String P_JAVALIB = "includeJavaLibraries";
	public static final String P_JAVALIBPART = "includePartialJavaLibraries";
	public static final String P_LOG_INFERRED_TYPES = "logInferredTypes";
	public static final String P_FFIQUALS = "qualsFileForFFIAnalysis";
	public static final String P_FFIANNOTE = "annotationsFileForFFIAnalysis";
	public static final String P_FFI = "doFFIAnalysis";
	public static final String P_FFISUBTYPES = "allowSubtypesInFFIAnalysis";
	public static final String P_JAVARI = "javariAnalysis";
	public static final String P_INTERNED = "inferInterned";
	public static final String P_LOG_CONSTRAINTS = "logConstraints";
	public static final String P_FFI_COUNT = "ffiNumPtrQuals";
	public static final String P_FFI_START = "ffiFirstPtrQuals";
	public static final String P_FFI_ENUMS = "ffiInferEnums";
	public static final String P_FFI_PUBLIC = "ffiPublic";
	public static final String P_FFI_TRANS = "ffiTransparent";
	public static String JQUAL_PREFS_PATH = JqualPlugin.workspaceRootDir
			+ "/jqual_prefs";
	public static PreferenceStore prefs;

	static {
		System.out.println(JQUAL_PREFS_PATH);
		try {
			boolean isNew = new File(JQUAL_PREFS_PATH).createNewFile();
			prefs = new PreferenceStore(JQUAL_PREFS_PATH);
			setDefaults(prefs);
			if (!isNew)
				prefs.load();
			else
				prefs.save();
		} catch (IOException e) {
			throw new RuntimeException("couldn't load prefs: " + e);
		}
	}

	public JqualPreferencePage() {
		super(1);

		setPreferenceStore(prefs);
		setDescription("JQual Configuration");
		initializeDefaults();
	}

	public IPreferenceStore doGetPreferenceStore() {
		return prefs;
	}

	public boolean performOk() {
		boolean ret = super.performOk();
		try {
			prefs.save();
		} catch (IOException e) {
			throw new RuntimeException("couldn't save prefs: " + e);
		}

		return ret;
	}

	private void initializeDefaults() {
		IPreferenceStore store = getPreferenceStore();
		setDefaults(store);
	}

	public static void setDefaults(IPreferenceStore store) {
		store.setDefault("latticePreference", JqualPlugin.workspaceRootDir
				+ "/jqual_examples/lattice");
		store.setDefault("logConstraints", false);
		store.setDefault("contextSensitive", false);
		store.setDefault("typeClosurePreference", true);
		store.setDefault("fieldSensitive", false);
		store.setDefault("obeyfieldSensitiveMarkups", true);
		store.setDefault("includeJavaLibraries", false);
		store.setDefault("logInferredTypes", false);
		store.setDefault("javariAnalysis", false);

		store.setDefault("useLongQualifierNamesPreference", true);
		store.setDefault("allowMerge", false);
		store.setDefault("showEmptyQualifiersPreference", false);
		store.setDefault("profilePreference", false);
		store.setDefault("debugPreference", false);
		store.setDefault("qualsFileForFFIAnalysis", "");
		store.setDefault("annotationsFileForFFIAnalysis", "");
		store.setDefault("ffiNumPtrQuals", 0);
		store.setDefault("ffiFirstPtrQuals", 0);
		store.setDefault("ffiInferEnums", false);
		store.setDefault("ffiPublic", false);
		store.setDefault("ffiTransparent", false);
		store.setDefault("doFFIAnalysis", false);
		store.setDefault("inferInterned", false);
		store.setDefault("allowSubtypesInFFIAnalysis", false);
		store.setDefault("includePartialJavaLibraries", false);
	}

	public void createFieldEditors() {
		addField(new FileFieldEditor("latticePreference",
				"JQual &lattice file:", getFieldEditorParent()));

		addField(new BooleanFieldEditor("contextSensitive",
				"Use context sensitivity", getFieldEditorParent()));

		addField(new BooleanFieldEditor("fieldSensitive",
				"Field-sensitive analysis", getFieldEditorParent()));
		addField(new BooleanFieldEditor(
				"obeyfieldSensitiveMarkups",
				"Obey F/S annotations on individual fields (selective field sensitivity)",
				getFieldEditorParent()));

		addField(new BooleanFieldEditor("typeClosurePreference",
				"Calculate transitive closure", getFieldEditorParent()));

		addField(new BooleanFieldEditor(
				"includeJavaLibraries",
				"Analyze full Java libraries (only happens if closure is checked above)",
				getFieldEditorParent()));

		addField(new BooleanFieldEditor("logInferredTypes",
				"Log inferred types (creates big file)", getFieldEditorParent()));

		addField(new BooleanFieldEditor("logConstraints",
				"Log constraints (creates big file...)", getFieldEditorParent()));

		addField(new BooleanFieldEditor("javariAnalysis",
				"Perform readonly analysis", getFieldEditorParent()));
	}

	public void init(IWorkbench workbench) {
		setPreferenceStore(prefs);
	}
}
